package com.algoshow.controller;

import com.algoshow.model.ListNode;
import com.algoshow.model.StackNode;
import com.algoshow.view.SecondMenu;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/**
 * @author vvv
 * @date 2023-05-28 08 30
 * discription
 */
public class StackAndQueuePage extends BasePage {

    private Stack<StackNode> st = new Stack<>();

    private List<StackNode> stringNode;

    private List<StackNode> stackNodes = new LinkedList<>();

    // 元素入栈的坐标
    private int stackX = 150;
    private int stackY = 800;
    private int offset = 50;

    private Integer i = 0;

    public StackAndQueuePage(List<StackNode> stringNode, String algoName) throws HeadlessException {
        this.stringNode = stringNode;
        this.algoName = algoName;


        firstMenuButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (timer != null && timer.isAlive()) {
                    timer.stop();
                }
                dispose();
                new SecondMenu().showTest6();
            }
        });
    }

    @Override
    public void drawAlgo(Graphics g) {
        // 画括号
        drawBracket(g);
        // 画栈
        drawStack(g);
    }

    @Override
    public void drawParam(Graphics g) {
        // 坐标
        int x = paramX, y = paramY;
        g.drawString("i = ", x, y);
        g.drawString(i.toString(), x + 35, y);
    }

    public void drawBracket(Graphics g) {
        Font font = new Font("Arial", Font.BOLD, 50);
        g.setFont(font);
        // 画string
        for (int i = 0; i < stringNode.size(); i++) {
            g.setColor(stringNode.get(i).color);
            StackNode node = stringNode.get(i);
            g.drawString(String.valueOf(node.value), node.x, node.y);
        }
    }

    public void drawStack(Graphics g) {

        int width = 150;  // 长方形的宽度
        int height = 800 + 50; // 长方形的高度
        int borderWidth = 5; // 边框宽度
        int x = 100; // 给定的x坐标
        int y = 400; // 给定的y坐标

        // 计算边框位置
        int borderX = x - borderWidth;
        int borderY = y;
        int borderHeight = height - y;

        // 绘制边框
        g.setColor(Color.BLACK);
        g.fillRect(borderX, borderY, borderWidth, borderHeight); // 左边框
        g.fillRect(borderX + width - borderWidth, borderY, borderWidth, borderHeight); // 右边框
        //g.fillRect(borderX, borderY, width, borderWidth); // 上边框
        g.fillRect(borderX, borderY + borderHeight - borderWidth, width, borderWidth); // 底边框
    }

    @Override
    public void startThread() {
        timer = new Thread() {
            @Override
            public void run() {
                switch (algoName) {
                    case "bracket":
                        bracketMatching();
                        break;
                    default:
                        timer.stop();
                }
            }

        };
        timer.start();
    }

    private boolean check(char left, char right) {
        if (left == '(' && right == ')' || left == '[' && right == ']' || left == '{' && right == '}') {
            return true;
        }
        return false;
    }

    public void bracketMatching() {
        render(0);
        if (stringNode.size() % 2 == 1) {
            render(1);
            fail();
            return;
        }
        render(2);
        boolean flag = true;
        for (i = 0; i < stringNode.size(); i++) {
            render(3);
            StackNode node = stringNode.get(i);
            char c = node.value;
            if (c == '(' || c == '[' || c == '{') {
                render(4);
                render(5,100);
                render(6,100);
                render(7,100);
                // 动画插入
                myPush(i);
                render();
                continue;
            }
            if (!st.isEmpty() && check(st.peek().value, c)) {
                render(8);
                render(9,100);
                render(10,100);
                render(11);
                //  动画删除
                myPop(i);
                render();
            } else {
                flag = false;
                render(8);
                render(12);
                render(13);
                break;
            }
        }
        if (!flag || !st.isEmpty()) {
           fail();
        }
        render(14);
    }

    private void fail() {
        for (StackNode stackNode : stringNode) {
            stackNode.color = red;
        }
        render();
    }

    public void myPush(int index) {
        // 动画
        StackNode node = stringNode.get(index);
        move(node, stackX, stackY, 5);
        stackY -= offset;
        st.push(stringNode.get(index));
    }

    public void myPop(int index) {
        // 把这个节点移到看不到的地方相当于删除
        StackNode node = stringNode.get(index);
        //move(node, stackX, stackY, 5);
        move(st.peek(), node.x - 30, node.y, 5);
        node.x = 100000;
        st.peek().x = 100000;
        stackY += offset;
        st.pop();
    }


    // 移动动画
    public void move(StackNode node, int endX, int endY, int speed) {
        while (node.x != endX || node.y != endY) {
            if (node.x < endX) {
                node.x += speed;
            } else if (node.x > endX) {
                node.x -= speed;
            }

            if (node.y < endY) {
                node.y += speed;
            } else if (node.y > endY) {
                node.y -= speed;
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            panel.repaint();
        }
        try {
            Thread.sleep(50);
        } catch (Exception e) {
            new RuntimeException(e);
        }
    }

    private void debug() {
        stringNode.forEach(System.out::println);
        System.out.println("===========================");
        stackNodes.forEach(System.out::println);
    }
}
